module mculib.arm.utils;


debug{
    /// 调试模式下，不使用内联函数 .
    enum __Inline = false;
}else{
    /// 发布模式下，使用内联函数
    enum __Inline = true;
}




//import std.meta:allSatisfy;
//import std.traits:isSomeString;







version(None):

import arm;
//import core.volatile;


import arm.stk;

import arm.builtins;
import core.attribute;

/// 定义寄存器位域读动作
enum RegBitFieldReadAction 
{
    /// 正常读取
    Normal,
    /// 读取时清除位域
    Clear,
    /// 读取时置位
    Set,
    /// 读取后修改
    Modify,

    ModifyExternal,
}
/// 定义寄存器位域写动作
enum RegBitFieldWriteAction 
{
    modify,         /// 修改寄存器位域
    oneToClear,     /// 置位后清除位域
    oneToSet,       /// 置位后置位
    oneToToggle,    /// 置位后反转位域
    zeroToClear,    /// 清除位域后清除
    zeroToSet,      /// 清除位域后置位
    zeroToToggle,   /// 清除位域后反转位域
    Clear,          /// 清除位域
    set             /// 置位位域
}



/**
    芯片封装类型
*/
enum ChipPackageType : uint
{
    WLCSP36_UFQFPN48_LQFP64 = 0x00,
    WLCSP168_FBGA169_LQFP100_LQFP64_UFQFPN48 = 0x100,
    WLCSP64_WLCSP81_LQFP176_UFBGA176 = 0x200,
    LQFP144_UFBGA144_UFBGA144_UFBGA100 = 0x300,
    LQFP100_LQFP208_TFBGA216 = 0x400,
    LQFP208_TFBGA216 = 0x500,
    TQFP64_UFBGA144_LQFP144 = 0x700,
}


final abstract class Utils
{
    /**
    * 使用 SysTick 的重载实现延时
    * time: 延时时间单位 由STK配置中的 TickFreq决定
    */
    pragma(inline,true)
    static void Delay(uint ms)
    {
        SysTick.GetCountFlag();
        while(ms)
        {
            if(SysTick.GetCountFlag())
            {
                ms--;
            }
        }
    }

    //@optStrategy("none") @noreturn 
    pragma(inline,true)
    static void DelayNOP(in uint mCount) 
    {
        uint mlop = mCount;

        while(mlop--)
        {
            __nop();
        }

    }
    /**
    * 设置优先级
    */
    /*
    static void PrioritySet(T)(T IRQn,uint Priority) if(is(T == IRQn_Core))
    in(IRQn < 0)
    {
        SCB.PrioritySet(IRQn,Priority);
    }
    
    static void PrioritySet(T)(T IRQn,uint Priority) if(is(T == IRQn_Ext))
    in(IRQn > 0)
    {
        NVIC.PrioritySet(IRQn,Priority);
    }
    
    static uint PriorityGet(T)(T IRQn) if(is(T == IRQn_Core))
    in(IRQn < 0)
    {
        return SCB.PriorityGet(IRQn);
    }
    static uint PriorityGet(T)(T IRQn) if(is(T == IRQn_Ext))
    in(IRQn > 0)
    {
        return NVIC.PriorityGet(IRQn);
    }
    */
}

/// 锁
struct SpinLock_Struct
{
    import core.atomic;
    
    shared(bool) lock;
    /**
    * 释放锁,任意情况下都会释放锁
    */
    void UnLock()
    {
        lock.atomicStore(false);
    }
    /**
    * 尝试加锁
    * Returns: true = 加锁成功 
    * Returns: false = 加锁失败,锁已经在使用中
    */
    bool tryLock()
    {
        return (&lock).cas(false,true);        
    }

    bool tryLock(uint timeout)
    {
        while(timeout--)
        {
            if(tryLock()) return true;
        }
        return false;
    }
    @property
    bool isLock() const
    {
        return lock;
    }
    alias isLock this;

}


package{



    uint EncodePriority (uint PriorityGroupA, uint PreemptPriority, uint SubPriority)
    {
        uint PriorityGroupTmp = (PriorityGroupA & 0x07); // 只使用值为1~7的二进制数
        uint PreemptPriorityBits;
        uint SubPriorityBits;

        PreemptPriorityBits = ((7 - PriorityGroupTmp) > (PriorityWidth)) ? (PriorityWidth) : (7 - PriorityGroupTmp);
        SubPriorityBits     = ((PriorityGroupTmp + (PriorityWidth)) < 7U) ? 0U : ((PriorityGroupTmp - 7U) + (PriorityWidth));

        return (
            ((PreemptPriority & ((1 << PreemptPriorityBits) - 1)) << SubPriorityBits) |
            ((SubPriority     & ((1 << SubPriorityBits)     - 1)))
            );
    }

    /// 反转二进制顺序
    T ReverseBits(T)(in T value) pure @nogc
    if (imported!"std.traits".isScalarType!T)
    {
        //import std.traits;
        enum asize = T.sizeof *8;
        T result = 0;
        for (uint i = 0; i < asize ; i++)
        {
            result |= ((value >> i) & 1) << (asize - i);
        }
        return result;
    }

}

